/////////////////////////////////////////////////////////////////////////
//
// Amuse Engine SDK - core
// Copyright (c) 2014.  All Rights Reserved
//
// File:		AETMap.h
// Author:		Gianluca Belardelli
// Date:		24/09/2013
//
/////////////////////////////////////////////////////////////////////////
#ifndef _AETMAP_H_
#define _AETMAP_H_

// The class TKEY is intended to be class data and must have the following
// member functions:
//   TKEY::TKEY ()
//   TKEY& TKEY::operator= (const TKEY&)
//   bool TKEY::operator== (const TKEY&) const
//   bool TKEY::operator!= (const TKEY&) const
//   TKEY::operator unsigned int () const
// The implicit conversion to unsigned int is used to select a hash table
// index from the key.
//
// The class TVALUE must have the following member functions:
//   TVALUE::TVALUE ()
//   TVALUE& TVALUE::operator= (const TVALUE&)

template <class TKEY, class TVALUE>
class AETMap
{
// Members
protected:
    class AEHashItem
    {
    public:
        TKEY		m_tKey;
        TVALUE		m_tValue;
        AEHashItem	*m_lpNext;
    };

    // key-to-index construction
    unsigned int HashFunction( const TKEY &tKey ) const;

    // hash table
    unsigned int	m_uiTableSize;
    unsigned int	m_uiSize;
    AEHashItem		**m_lplpTable;

    // iterator for traversal
    unsigned int	m_uiIndex;
    AEHashItem		*m_lpItem;

// Methods
public:
    // construction and destruction
    AETMap( unsigned int uiTableSize );
    ~AETMap( void );

    // element access
    unsigned int GetSize( void ) const;
    bool IsEmpty( void ) const;
    bool SetAt( const TKEY &tKey, const TVALUE &tValue );
    bool GetAt( const TKEY &tKey, TVALUE &tValue ) const;
    bool RemoveAt( const TKEY &tKey );
    void RemoveAll( void );

	TVALUE operator[] ( const TKEY &tKey ) const;
	TVALUE &operator[] ( const TKEY &tKey );

    // linear traversal of map
    bool GetFirst( TKEY &tKey, TVALUE &tValue );
    bool GetNext( TKEY &tKey, TVALUE &tValue );
};

#include "AETMap.inl"

#endif // _AETMAP_H_
